package com.bbtShop.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bbtShop.config.BizException;
import com.bbtShop.core.model.RegionDto;
import com.bbtShop.core.model.ResultCode;
import com.bbtShop.core.model.SysLoginLog;
import com.bbtShop.core.model.SysUser;
import com.bbtShop.core.utils.HttpClientUtil;
import com.bbtShop.core.utils.IpToAddrUtil;
import com.bbtShop.core.utils.IpUtil;
import com.bbtShop.service.SysUserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.catalina.User;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;

import static com.bbtShop.aop.AnnotationParse.*;
import static com.bbtShop.core.model.SysLoginLog.login;

/**
 * @author : manke
 * @Description
 * @Date: 2020/10/31 11:09
 */

@Aspect
@Component
public class ControllerAspect {
    @Autowired
    private IpToAddrUtil ipToAddrUtil;

    @Autowired
    private AnnotationParse annotationParse;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private HttpServletRequest request;


    private static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);

    //定义切点
    @Pointcut("execution(public * com.bbtShop.api.*.*(..))")
    private void login() {

    }

    @Around("login()")
    public Object isAccessMethod(ProceedingJoinPoint proceedingJoinPoint)
            throws Throwable {
        //获取访问目标方法
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = methodSignature.getMethod();
        //得到方法的访问权限
        Integer flag = annotationParse.LoginParse(method);
        //如果该方法上没有权限注解，直接调用目标方法
        if (flag == flag_no_token) {
            logger.info("==========未携带token");
            throw new BizException(ResultCode.LOGIN_PAST);
        }
        if (flag == flag_failed) {
            logger.info("==========token验证失败");
            throw new BizException(ResultCode.LOGIN_PAST);
        }
        if (flag == flag_no_permission) {
            logger.info("==========无权限");
            throw new BizException(ResultCode.NO_PERMISSION);
        }
        System.out.println("---");
        return proceedingJoinPoint.proceed();

    }

    //定义切点
    @Pointcut("execution(public * com.bbtShop.service.SysUserService.login(..))")
    private void LoginLog() {
    }

    @Around("LoginLog()")
    public String LoginLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object[] args = proceedingJoinPoint.getArgs();
        String proceed = (String) proceedingJoinPoint.proceed(args);
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        RequestContextHolder.setRequestAttributes(sra, true);
        Thread t = new Thread(new Runnable() {
            public void run() {
                String ipAddr = IpUtil.getIpAddr(request);
                SysUser sysUser = new SysUser();
                if (args.length > 0) {
                    ObjectMapper objectMapper = new ObjectMapper();
                    sysUser = objectMapper.convertValue(args[0], SysUser.class);
                }
                SysLoginLog sysLoginLog = new SysLoginLog();
                //获取ip地址
                RegionDto addr = ipToAddrUtil.Addr(ipAddr);
                sysLoginLog.setProvince(addr.getProvince());
                sysLoginLog.setCity(addr.getCity());
                sysLoginLog.setAccount(sysUser.getAccount());
                sysLoginLog.setCreatetime(new Date());
                sysLoginLog.setIp(ipAddr);
                sysLoginLog.setType(login);
                sysUserService.sysLoginLog(sysLoginLog);
            }
        });
        t.start();
        return proceed;


    }


}
